package org.lh.ibernate.core.invoker;

import org.lh.ibernate.annotation.Id;
import org.lh.ibernate.annotation.Query;
import org.lh.ibernate.core.ISessionUtil;
import org.lh.ibernate.core.tools.ParameterLink;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

/*
 *
 * @author idea
 * @date 2018/7/12
 * @des 主要用于提供给org.lh.ibernate.core.invoker.MethodProxy里面的run使用，优化代码
 */
public class AnnotationHandle<T,PK> {

    /*
    *
    * @author idea
    * @date 2018/7/12
    * @param Method method, Object[] args, ISessionUtil sessionUtil
    * @return Object
    * @des 查询处理
    */
    public  Object queryHandle(Method method, Object[] args, ISessionUtil sessionUtil) throws Exception {
        Class<T> returnType= (Class<T>) method.getReturnType();
        Query query=(Query)method.getAnnotation(Query.class);
        String sql=query.value();
        ParameterLink plink=new ParameterLink();
        if(args!=null){
            for (Object arg : args) {
                plink.add(arg);
            }
        }
        List<T> result=  sessionUtil.queryCustom(sql,plink);
        if(returnType.getName().indexOf("java.util.List")<0){ //返回的类型不是集合类型
            return result.get(0);
        }
        return result;
    }

    public T findOne(Method method, Object[] args,ISessionUtil sessionUtil,T resultType) throws Exception {
        if(args!=null) {
               PK pk= (PK) args[0];
               return (T) sessionUtil.findOne(resultType,pk);
//            }
        }
        return null;
    }


    public List<T> findAll(Method method, Object[] args,ISessionUtil sessionUtil,T resultType) throws Exception {
            return (List<T>) sessionUtil.findAll(resultType.getClass());
    }


    public List<T> batchInsertHandle(Method method, Object[] args,ISessionUtil sessionUtil) throws Exception {
        if(args!=null) {
            List<T> objList= (List<T>) args[0];
            return sessionUtil.batchInsert(objList);
        }
       return null;
    }

    public List<T> callableStatementHandle(Method method, String value,ISessionUtil sessionUtil) throws Exception {
        if(value!=null) {
          return sessionUtil.queryCallHandle(value);
        }
        return null;
    }


    /*
     *
     * @author idea
     * @date 2018/7/12
     * @param Method method, Object[] args, ISessionUtil sessionUtil
     * @return Object
     * @des 插入处理
     */
    public  Object insertHandle(Method method, Object[] args, ISessionUtil sessionUtil) throws Exception {
        if(args!=null){
            sessionUtil.save((T) args[0]); //一次只允许插入一个对象
            return args[0];
        }
        return null;
    }


    /*
     *
     * @author idea
     * @date 2018/7/12
     * @param Method method, Object[] args, ISessionUtil sessionUtil
     * @return Object
     * @des 更新处理
     */
    public  Object updateHandle(Method method, Object[] args, ISessionUtil sessionUtil) throws Exception {
        if(args!=null){
            sessionUtil.update(args[0], (PK) findObjPk(args[0]));
            return args[0];
        }
       return null;
    }


    /*
     *
     * @author idea
     * @date 2018/7/12
     * @param Method method, Object[] args, ISessionUtil sessionUtil
     * @return Object
     * @des 删除处理
     */
    public  Object deleteHandle(Method method, Object[] args, ISessionUtil sessionUtil) throws Exception {
        if(args!=null){
            Class<T> tClass= (Class<T>) args[0].getClass();
            sessionUtil.delete(tClass,(PK) findObjPk(args[0]));
            return args[0];
        }
        return null;
    }


    /*
     *
     * @author idea
     * @date 2018/7/12
     * @param Method method, Object[] args, ISessionUtil sessionUtil
     * @return Object
     * @des 根据一个实体类主键来查找相应的id值
     */
    private Object findObjPk(Object object) throws IllegalAccessException {
        Field[] fieldArr=object.getClass().getDeclaredFields();
        Object pk=new Object();
        for (Field field : fieldArr) {
            if (field.isAnnotationPresent(Id.class)){
                field.setAccessible(true);
                pk=field.get(object);
                break;
            }
        }
        return pk;
    }
}
